package com.qijian.plug.capacity.approval;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.qijian.common.annotation.Log;
import com.qijian.common.core.domain.entity.FlowablModelApproval;
import com.qijian.common.enums.ApprovalDescriptionEnum;
import com.qijian.common.enums.BusinessType;
import com.qijian.common.exception.ServiceException;
import com.qijian.common.utils.DateUtils;
import com.qijian.common.utils.mybatis.WhereEntityTool;
import com.qijian.flowable.domain.FlowableForm;
import com.qijian.flowable.domain.FlowableRecord;
import com.qijian.flowable.domain.query.FlowableRecordQuery;
import com.qijian.flowable.domain.vo.ProcessInstanceVo;
import com.qijian.flowable.service.IFlowableFormService;
import com.qijian.flowable.service.IFlowableRecordService;
import com.qijian.flowable.service.IProcessInstanceService;
import com.qijian.tool.domain.Msg;
import com.qijian.tool.service.IMsgService;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author qijian
 */
@Component
@RequiredArgsConstructor
public class ApprovalModelProcess extends ApprovalPlugWrapper<FlowablModelApproval.Approval> {

    private final IProcessInstanceService processInstanceService;
    private final RepositoryService repositoryService;
    private final IFlowableFormService flowableFormService;
    private final IFlowableRecordService flowableRecordService;
    private final IMsgService msgService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doSomething(List<Object> args) {
        this.operation(args);
    }

    @Log(title = "流程发起", businessType = BusinessType.APPROVAL)
    protected void operation(List<Object> args) {
        // ID
        List<Long> ids = (List<Long>) args.get(0);
        for (Long id :ids) {
            String processDefinitionKey = args.get(1).toString();
            Map<String, Object> values = new HashMap<>(3);
            // 流程
            ApprovalDescriptionEnum status = null;
            // 用户
            Long userId = ObjectUtil.isNotNull(args.get(2)) ? Long.valueOf(args.get(2).toString()) : null;
            // 部门
            Long deptId = ObjectUtil.isNotNull(args.get(3)) ? Long.valueOf(args.get(3).toString()) : null;
            // 用户名称
            String nickName = ObjectUtil.isNotNull(args.get(4)) ? args.get(4).toString() : null;
            String title = nickName;
            String content = "";
            String title1 = "";
            if ("hr_accident".equals(processDefinitionKey)) {
                // 安全事故
//                AccidentDealReport accidentdealreport = accidentReportService.getById(id);
//                values.put("director",accidentdealreport.getDirector());
//                status = accidentdealreport.getApprovalStatus();
//                title1 = String.format("%s-",accidentdealreport.getCode());
//                title = String.format("%s-%s", "事故报告流程",accidentdealreport.getCode());
//                content = "您收到一条事故报告申请";
//                List<AccidentUsers> users = accidentUsersMapper.selectList(new LambdaQueryWrapper<AccidentUsers>().eq(AccidentUsers::getSourceId, id));
//                values.put("userList",users.stream().map(e->e.getUserId()).collect(Collectors.toList()));
            }
            values.put("userId", userId);
            values.put("deptId", deptId);
            values.put("nickName", title1);
            values.put("title", title);

            if (status == null) {
                throw new ServiceException("单据信息错误！");
            }

            FlowableRecordQuery recordQuery = new FlowableRecordQuery();
            recordQuery.setBusinessKey(processDefinitionKey);
            recordQuery.setSourceId(id);
            FlowableRecord flowableRecord = flowableRecordService.getOne(WhereEntityTool.invoke(recordQuery));
            status = flowableRecord == null ? ApprovalDescriptionEnum.A : status;
            if (flowableRecord != null && status.getValue().equals(flowableRecord.getStatus())) {
                throw new ServiceException("单据状态错误！");
            } else if (status == ApprovalDescriptionEnum.B) {
                throw new ServiceException("单据审核中！");
            } else if (status == ApprovalDescriptionEnum.C) {
                throw new ServiceException("单据已审核！");
            }
            // 查询流程
            ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
            processDefinitionQuery.processDefinitionKey(processDefinitionKey).latestVersion();
            ProcessDefinition definition = processDefinitionQuery.singleResult();
            if (ObjectUtil.isNotNull(definition)) {
                // 流程表单
                FlowableForm flowableForm = flowableFormService.getById(processDefinitionKey);
                JSONArray jsonField = JSONUtil.parseObj(flowableForm.getFormJson()).getJSONArray("list");
                String idField = null;
                for (int i = 0; i < jsonField.size(); i++) {
                    if ("ID".equals(jsonField.getJSONObject(i).getStr("name"))) {
                        idField = jsonField.getJSONObject(i).getStr("model");
                        break;
                    }
                }

                if (idField == null) {
                    throw new ServiceException("流程表单错误！");
                }

                // 流程数据
                ProcessInstanceVo instanceVo = new ProcessInstanceVo();
                instanceVo.setProcessDefinitionId(definition.getId());
                values.put("isFunction", false);
                values.put(idField, id.toString());
                values.put("approvalData", DateUtils.getDate());
                values.put("processInstanceFormData", JSONUtil.toJsonStr(values));
                values.put("createId", userId);
                instanceVo.setValues(values);
                instanceVo.setSourceId(id);
                // 发起流程
                Map<String, Object> result = processInstanceService.start(instanceVo);
                String processInstanceId = (String) result.get("processInstanceId");
                String processTitle = (String) result.get("title");
                List<Msg> msgs = new ArrayList<>(16);
                if (result.get("parent") != null) {
                    Msg msg = new Msg();
                    msg.setSourceId(processInstanceId);
                    msg.setSourceType(processDefinitionKey);
                    msg.setUserId((Long) result.get("parent"));
                    msg.setTitle(processTitle);
                    msg.setCreateBy(nickName);
                    msg.setContent(content);
                    msgs.add(msg);
                }
                if (result.get("users") != null) {
                    List<String> userList = (List<String>) result.get("users");
                    for (String u : userList) {
                        Msg msg = new Msg();
                        msg.setSourceId(processInstanceId);
                        msg.setSourceType(processDefinitionKey);
                        msg.setUserId(Long.valueOf(u));
                        msg.setTitle(processTitle);
                        msg.setCreateBy(nickName);
                        msg.setContent(content);
                        msgs.add(msg);
                    }
                }
                if (result.get("groups") != null) {
                    List<String> groupList = (List<String>) result.get("groups");
                }

                if (CollectionUtil.isNotEmpty(msgs)) {
                    msgService.saveBatch(msgs);
                }
            }
        }
        // 流程Key

    }
}
